/***
 * @Description: 本文件将主要是实现网络接口协议的相关功能结构设计和数据结构定义的C语言文件
 * @Author: Liverpool
 * @Date: 2024-04-22 01:31:46
 * @LastEditTime: 2024-04-24 01:07:23
 * @LastEditors: Liverpool
 */

#include "net_Interface.h"
#include "packet.h"
#include "MessageHander.h"
#include "protocol.h"
#include "ethernet.h"

// 网络接口变量定义区
static D_Net_Interface net_Interface_buffer[Net_Interface_Device_Cnt]; // 存储所有的网卡变量
static D_MemoryBlock net_Interface_MemoryBlock;                        // 对网卡资源进行内存管理分配
static D_List net_Interface_List;                                      // 激活后的网卡需要加入该链表队列
static D_Net_Interface *net_Interface_Default;                         // 默认的网络接口发送接收数据
// 数据链路层变量定义区
static const D_Link_Layer *link_layers[NET_Interface_SIZE];

#if Debug_Display_Enable(Debug_NetInterface)
/***
 * @description: debug打印所有的在列表中的网络接口信息
 * @Author: Liverpool
 * @Date: 2024-05-05 23:25:35
 * @return {*}
 */
void display_net_interface_list(void)
{
    plat_printf("net interface list\n");
    D_ListNode *node;
    list_for_each_node(node, &net_Interface_List)
    {
        D_Net_Interface *netif = list_entry(node, D_Net_Interface, node);
        plat_printf("%s:", netif->name);
        switch (netif->state)
        {
        case NET_Interface_Closed:
            plat_printf(" %s ", "closed");
            break;
        case NET_Interface_Open:
            plat_printf(" %s ", "open");
            break;
        case NET_Interface_Active:
            plat_printf(" %s ", "active");
            break;
        default:
            break;
        }
        switch (netif->type)
        {
        case NET_Interface_ETHER:
            plat_printf(" %s ", "ethernet");
            break;
        case NET_Interface_LOOP:
            plat_printf(" %s ", "loopBack");
            break;
        default:
            break;
        }
        plat_printf(" mtu: %d \n", netif->mtu);
        debug_dump_hwaddr("hwaddr:", netif->hwaddr.address, netif->hwaddr.len);
        debug_dump_ipaddr(" ip:", &netif->ipaddr);
        debug_dump_ipaddr(" netmask:", &netif->netmask);
        debug_dump_ipaddr(" gateway:", &netif->gateway);
        plat_printf("\n");
    }
}
#else
#define display_net_interface_list()
#endif

/***
 * @description: 网络接口的模块的初始化函数，支持多网卡配置
 * @Author: Liverpool
 * @Date: 2024-04-24 01:08:56
 * @return {*} 初始化过程中发生的错误
 */
net_err_t net_interface_init(void)
{
    debug_info(Debug_NetInterface, "net interface init");

    list_init(&net_Interface_List);                                                                                                      // 初始化网卡链表
    memory_block_init(&net_Interface_MemoryBlock, net_Interface_buffer, sizeof(D_Net_Interface), Net_Interface_Device_Cnt, Locker_Self); // 初始化网卡的内存分配(只有一个线程访问网卡，所以不需要锁)
    net_Interface_Default = (D_Net_Interface *)0;
    plat_memset((void *)link_layers, 0, sizeof(link_layers));
    debug_info(Debug_NetInterface, "net interface init done");
    return NET_ERR_OK;
}
/***
 * @description: 网络接口的数据链路层的注册函数，在数据链路层存储数组中注册这个网络接口相关的数据链路层内容
 * @Author: Liverpool
 * @Date: 2024-05-15 20:31:47
 * @return {*}
 * @param {int} type 网络接口类型
 * @param {D_Link_Layer} *layer 存储数据链路层的数据包的内存地址
 */
net_err_t net_interface_register_layer(int type, const D_Link_Layer *layer)
{
    if ((type < 0) || (type >= NET_Interface_SIZE))
    {
        debug_error(Debug_NetInterface, "type error");
        return NET_ERR_PARAM;
    }
    if (link_layers[type])
    {
        debug_error(Debug_NetInterface, "link layer exist");
        return NET_ERR_EXIST;
    }
    link_layers[type] = layer;
    return NET_ERR_OK;
}
/***
 * @description: 根据网络接口类型来选择数据链路层的接口函数
 * @Author: Liverpool
 * @Date: 2024-05-15 22:17:51
 * @return {*} 在数据链路层数组中的对应的数据链路层的回调函数结构体的内存地址
 * @param {int} type 网络接口类型
 */
static const D_Link_Layer *net_interface_get_layer(int type)
{
    if (type < 0 || type >= NET_Interface_SIZE)
    {
        debug_error(Debug_NetInterface, "type error");
        return (const D_Link_Layer *)0;
    }
    return link_layers[type];
}

/***
 * @description: 打开网络接口，软件配置打开
 * @Author: Liverpool
 * @Date: 2024-04-28 00:12:30
 * @return {*} 返回打开的网络接口地址
 * @param {char} *dev_name 需要打开的网络接口的名称
 * @param {D_Net_Interface_operation} *operation 外部定义好的硬件操作结构体地址
 * @param {void} *operation_data 硬件操作数据
 */
D_Net_Interface *net_interface_open(const char *dev_name, const D_Net_Interface_operation *operation, void *operation_data)
{
    D_Net_Interface *netif = (D_Net_Interface *)memory_block_alloc(&net_Interface_MemoryBlock, -1); // 分配一个网络接口空间
    if (!netif)
    {
        debug_error(Debug_NetInterface, "no net_interface...");
        return (D_Net_Interface *)0;
    }
    // 对网络接口进行初始化
    ip_addr_set_any(&netif->ipaddr);
    ip_addr_set_any(&netif->netmask);
    ip_addr_set_any(&netif->gateway);

    plat_strncpy(netif->name, dev_name, Net_Interface_Name_Size);
    netif->name[Net_Interface_Name_Size - 1] = '\0';
    plat_memset(&netif->hwaddr, 0, sizeof(D_Net_Interface_HWaddr));
    netif->type = Net_Interface_None;
    netif->mtu = 0;
    list_node_init(&netif->node);

    net_err_t err = fix_queue_init(&netif->in_queue, netif->in_queue_buf, NET_InQueue_Size, Locker_Thread);
    if (err < 0)
    {
        debug_error(Debug_NetInterface, "net interface in_queue init failed...");
        memory_block_free(&net_Interface_MemoryBlock, netif);
        return (D_Net_Interface *)0;
    }
    err = fix_queue_init(&netif->out_queue, netif->out_queue_buf, NET_InQueue_Size, Locker_Thread);
    if (err < 0)
    {
        debug_error(Debug_NetInterface, "net interface out_queue init failed...");
        fix_queue_destroy(&netif->in_queue);
        memory_block_free(&net_Interface_MemoryBlock, netif);
        return (D_Net_Interface *)0;
    }
    // 硬件接口映射
    netif->operation = operation;
    netif->operation_data = operation_data;
    err = operation->open(netif, operation_data);
    if (err < 0)
    {
        debug_error(Debug_NetInterface, "net interface operation open err...");
        goto free_return;
    }
    netif->state = NET_Interface_Open;
    if (netif->type == Net_Interface_None)
    {
        debug_error(Debug_NetInterface, "net interface type unknown... ");
        goto free_return;
    }
    netif->link_layer = net_interface_get_layer(netif->type);
    if (!netif->link_layer && (netif->type != NET_Interface_LOOP))
    {
        debug_error(Debug_NetInterface, "no link layer,netif name:%s", dev_name);
        goto free_return;
    }
    list_insert_last(&net_Interface_List, &netif->node); // 插入带网络接口链表中
    display_net_interface_list();
    return netif;
free_return:
    if (netif->state == NET_Interface_Open)
    {
        netif->operation->close(netif);
    }

    fix_queue_destroy(&netif->in_queue);
    fix_queue_destroy(&netif->out_queue);
    memory_block_free(&net_Interface_MemoryBlock, netif);
    return (D_Net_Interface *)0;
}

/***
 * @description: 关闭网络接口
 * @Author: Liverpool
 * @Date: 2024-05-07 22:11:17
 * @return {*} 在关闭过程中产生的错误
 * @param {D_Net_Interface} *netif 需要关闭的网络接口内存地址
 */
net_err_t net_interface_close(D_Net_Interface *netif)
{
    if (netif->state == NET_Interface_Active)
    {
        debug_error(Debug_NetInterface, "netif is active");
        return NET_ERR_STATE;
    }
    netif->operation->close(netif); // 对硬件底层进行关闭
    netif->state = NET_Interface_Closed;
    list_remove_node(&net_Interface_List, &netif->node);  // 需要从网络接口链表中移除该节点
    memory_block_free(&net_Interface_MemoryBlock, netif); // 内存管理回收该网络接口
    display_net_interface_list();
    return NET_ERR_OK;
}

/***
 * @description: 为网络接口设置IP地址相关的内容
 * @Author: Liverpool
 * @Date: 2024-05-05 15:35:35
 * @return {*} 在设置过程中出现的错误
 * @param {D_Net_Interface} *netif 网络接口地址
 * @param {D_IP_ADDR} *ip IP地址
 * @param {D_IP_ADDR} *netmask 子网掩码
 * @param {D_IP_ADDR} *gateway 网关
 */
net_err_t net_interface_set_addr(D_Net_Interface *netif, D_IP_ADDR *ip, D_IP_ADDR *netmask, D_IP_ADDR *gateway)
{
    // 复制相应的IP地址到网络接口
    ipaddr_copy(&netif->ipaddr, ip ? ip : ipaddr_get_any());
    ipaddr_copy(&netif->netmask, netmask ? netmask : ipaddr_get_any());
    ipaddr_copy(&netif->gateway, gateway ? gateway : ipaddr_get_any());
    return NET_ERR_OK;
}
/***
 * @description: 在网络接口设置硬件地址
 * @Author: Liverpool
 * @Date: 2024-05-05 15:39:11
 * @return {*} 在设置过程中的错误
 * @param {D_Net_Interface} *netif 需要设置的网络接口内存地址
 * @param {char} *hwaddr 硬件地址的内存地址
 * @param {int} len 硬件地址的长度
 */
net_err_t net_interface_set_HWaddr(D_Net_Interface *netif, const char *hwaddr, int len)
{
    plat_memcpy(netif->hwaddr.address, hwaddr, len);
    netif->hwaddr.len = len;
    return NET_ERR_OK;
}
/***
 * @description: 对于网络接口的激活
 * @Author: Liverpool
 * @Date: 2024-05-05 22:24:36
 * @return {*} 在激活过程中发生的错误
 * @param {D_Net_Interface} *netif 需要激活的网络接口内存地址
 */
net_err_t net_interface_set_active(D_Net_Interface *netif)
{
    if (netif->state != NET_Interface_Open)
    {
        debug_error(Debug_NetInterface, "net interface is not opened");
        return NET_ERR_STATE;
    }
    netif->state = NET_Interface_Active;
    // 当目前缺省网络接口为空并且不为回环网卡的时候，需要对缺省网卡进行设置
    if (!net_Interface_Default && (netif->type != NET_Interface_LOOP))
    {
        net_interface_set_default(netif);
    }
    // 如果有数据链路层，需要打开数据链路层
    if (netif->link_layer)
    {
        net_err_t err = netif->link_layer->open(netif);
        debug_info(Debug_NetInterface, "active error...");
        return err;
    }
    display_net_interface_list();
    return NET_ERR_OK;
}
/***
 * @description:
 * @Author: Liverpool
 * @Date: 2024-05-05 22:35:47
 * @return {*}
 * @param {D_Net_Interface} *netif
 */
net_err_t net_interface_set_deactive(D_Net_Interface *netif)
{
    if (netif->state != NET_Interface_Active)
    {
        debug_error(Debug_NetInterface, "net interface is not actived");
        return NET_ERR_STATE;
    }
    // 关闭数据链路层
    if (netif->link_layer)
    {
        netif->link_layer->close(netif);
    }
    // 对于网络接口的收发队列需要进行清除
    D_Packet
        *buf;
    while ((buf = fix_queue_receive(&netif->in_queue, -1)) != (D_Packet *)0)
    {
        packet_free(buf);
    }
    while ((buf = fix_queue_receive(&netif->out_queue, -1)) != (D_Packet *)0)
    {
        packet_free(buf);
    }
    // 如果当前网卡是默认网络接口那就需要清除
    if (net_Interface_Default == netif)
    {
        net_Interface_Default = (D_Net_Interface *)0;
    }
    netif->state = NET_Interface_Open;
    display_net_interface_list();
    return NET_ERR_OK;
}

/***
 * @description: 设置缺省网络接口(也就是默认网络接口)
 * @Author: Liverpool
 * @Date: 2024-05-07 22:08:27
 * @return {*}
 * @param {D_Net_Interface} *netif 需要进行设置的网络接口内存地址
 */
void net_interface_set_default(D_Net_Interface *netif)
{
    net_Interface_Default = netif;
}

/***
 * @description: 获取缺省网络接口(也就是默认网络接口)
 * @Author: Liverpool
 * @Date: 2024-07-11 14:20:32
 * @return {*} 缺省网络接口的内存地址
 */
D_Net_Interface *net_interface_get_default(void)
{
    return net_Interface_Default;
}

/***
 * @description: 往协议栈网卡的输入队列中去写入相应的数据包
 * @Author: Liverpool
 * @Date: 2024-05-07 23:06:01
 * @return {*} 写入过程中产生的错误
 * @param {D_Net_Interface} *netif 需要写入对应的网卡内存地址
 * @param {D_Packet} *buf 写入数据包的内存地址
 * @param {int} ms 写入最多等待的时间
 */
net_err_t net_interface_put_in(D_Net_Interface *netif, D_Packet *buf, int ms)
{
    net_err_t err = fix_queue_send(&netif->in_queue, buf, ms); // 添加到网卡的输入队列中去
    if (err < 0)
    {
        debug_Warning(Debug_NetInterface, "netif:%s in_queue is full", netif->name);
        return NET_ERR_FULL;
    }
    message_handler_netif_in(netif); // 给消息处理机制的消息队列发送已经有网卡信息了
    return NET_ERR_OK;
}

/***
 * @description: 从协议栈网卡的输入队列中读取相应的数据包
 * @Author: Liverpool
 * @Date: 2024-05-07 23:22:20
 * @return {*} 读取的数据包的内存地址
 * @param {D_Net_Interface} *netif 需要读取的网卡内存地址
 * @param {int} ms 读取最多等待的时间
 */
D_Packet *net_interface_get_in(D_Net_Interface *netif, int ms)
{
    D_Packet *buf = fix_queue_receive(&netif->in_queue, ms);
    if (buf)
    {
        packet_reset_access(buf); // 需要对数据包的数据内容进行初始化
        return buf;
    }
    debug_info(Debug_NetInterface, "netif:%s in_queue is emptry", netif->name);
    return (D_Packet *)0;
}

/***
 * @description: 往协议栈网卡的输出队列中去写入相应的数据包
 * @Author: Liverpool
 * @Date: 2024-05-07 23:31:25
 * @return {*} 写入过程中产生的错误
 * @param {D_Net_Interface} *netif 需要写入对应的网卡内存地址
 * @param {D_Packet} *buf 写入数据包的内存地址
 * @param {int} ms 写入最多等待的时间
 */
net_err_t net_interface_put_out(D_Net_Interface *netif, D_Packet *buf, int ms)
{
    net_err_t err = fix_queue_send(&netif->out_queue, buf, ms); // 添加到网卡的输入队列中去
    if (err < 0)
    {
        debug_Warning(Debug_NetInterface, "netif:%s out_queue is full", netif->name);
        return NET_ERR_FULL;
    }
    return NET_ERR_OK;
}

/***
 * @description: 从协议栈网卡的输出队列中读取相应的数据包
 * @Author: Liverpool
 * @Date: 2024-05-07 23:22:20
 * @return {*} 读取的数据包的内存地址
 * @param {D_Net_Interface} *netif 需要读取的网卡内存地址
 * @param {int} ms 读取最多等待的时间
 */
D_Packet *net_interface_get_out(D_Net_Interface *netif, int ms)
{
    D_Packet *buf = fix_queue_receive(&netif->out_queue, ms);
    if (buf)
    {
        packet_reset_access(buf); // 需要对数据包的数据内容进行初始化
        return buf;
    }
    debug_info(Debug_NetInterface, "netif:%s out_queue is emptry", netif->name);
    return (D_Packet *)0;
}

/***
 * @description: 网卡向外发送数据包
 * @Author: Liverpool
 * @Date: 2024-05-08 01:29:14
 * @return {*} 发送过程中产生的错误
 * @param {D_Net_Interface} *netif 发送的网络接口内存地址
 * @param {D_IP_ADDR} *ipaddr 需要发送的IP地址
 * @param {D_Packet} *buf 需要发送的数据包内存地址
 */
net_err_t net_interface_out(D_Net_Interface *netif, D_IP_ADDR *ipaddr, D_Packet *buf)
{
    if (netif->link_layer)
    {
        net_err_t err = netif->link_layer->out(netif, ipaddr, buf); // 调用数据链路层的发送函数
        if (err < 0)
        {
            debug_Warning(Debug_NetInterface, "netif link out err!");
            return err;
        }
        return NET_ERR_OK;
    }
    else
    {
        net_err_t err = net_interface_put_out(netif, buf, -1); // 在输出队列写入需要发送的东西
        if (err < 0)
        {
            debug_info(Debug_NetInterface, "send failed,netif:%s out_queue is full", netif->name);
            return err;
        }
        return netif->operation->transmit(netif); // 硬件底层发送数据包
    }
}